﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once

#include <QTreeWidget>
#include <QIcon>
#include <QMap>

namespace gcmp
{
    class IDocument;
    class IFamily;
    class IElement;
}

#define FAMILY_USER_DATA_ROLE (Qt::UserRole+100)
#define MODEL_VIEW_USER_DATA_ROLE (Qt::UserRole+101)
#define IMPORT_USER_DATA_ROLE (Qt::UserRole+103)
#define IMPORT_ITEM_FAMILY_TYPE (Qt::UserRole + 1)
#define PAPER_USER_DATA_ROLE (Qt::UserRole+102)
#define GROUP_USER_DATA_ROLE (Qt::UserRole+104)
#define GROUP_ITEM_TYPE (Qt::UserRole + 105)


class QIconMap
{
public:
    QIcon GetIcon(const QString& path)
    {
        if (m_icons.contains(path))
        {
            return m_icons.value(path);
        }
        else
        {
            auto itr = m_icons.insert(path, QIcon(path));
            return itr.value();
        }
    }

private:
    QMap<QString, QIcon> m_icons;
};

enum EnTreeWidgetNodeType
{
    // 族
    TWNT_FAMILY_ROOT = 1,
    TWNT_FAMILY_CATEGORY,
    TWNT_FAMILY,
    TWNT_FAMILYTYPE,

    // 导入对象
    TWNT_IMPORTED_OBJECT_ROOT,
    TWNT_CAD_SHEET_CATEGORY,
    TWNT_CAD_SHEET,
    TWNT_SKP_MODEL_CATEGORY,
    TWNT_SKP_MODEL,

    // 组
    TWNT_GROUP_OBJECT_ROOT,
    TWNT_GROUP_MODEL_CATEGORY,
    TWNT_GROUP_MODEL
};


class QFamilyTreeWidgetUtil
{
public:
    static const QString s_familyText;
    static const QString s_importedObjectText;
    static const QString s_cadSheetCategoryText;
    static const QString s_skpCategoryText;
    static const QString s_groupTypeText;

    static void UpdateFamilyItems(QTreeWidgetItem *pFamilyRootItem, gcmp::IDocument* pDoc, QIconMap& mapIcons);
    static void UpdateImportedObjectItems(QTreeWidget* pTreeWidget, gcmp::IDocument* pDoc, QIconMap& mapIcons);
    static void UpdateGroupObjectItems(QTreeWidget* pTreeWidget, gcmp::IDocument* pDoc, QIconMap& mapIcons);

    static QTreeWidgetItem* AddFamilyCategoryWidgetItem(QTreeWidgetItem* pParent, const QString& categoryName, QIconMap& mapIcons);
    static QTreeWidgetItem* FindChildWidgetItem(QTreeWidgetItem* pParent, const std::wstring& itemName);
    static void AddFamilyWidgetItem(QTreeWidgetItem* pParent, gcmp::IFamily* pFamily, QIconMap& mapIcons);
    static void UpdateFamilyWidgetItem(QTreeWidgetItem* pFamilyItem, gcmp::IFamily* pFamily, QIconMap& mapIcons);
    static void MarkFamilyAndTypeWidgetItemDirty(QTreeWidgetItem* pRoot);
    static void DeleteDirtyChildItem(QTreeWidgetItem* pParent);
    static QTreeWidgetItem* FindTopLevelWidgetItem(QTreeWidget* pTreeWidget, const QString& itemName);

    // 导入对象可能是Family也可能是Element，下面两个方法会处理这两种类型
    static void BuildImportedObjectWidgetItems(QTreeWidget* pTreeWidget, QIconMap& mapIcons, const std::vector<gcmp::IElement*>& importedObjects);
    static void DeleteImportedObjectWidgetItem(QTreeWidget* pTreeWidget, gcmp::IElement* pDeletingObject);

    static void BuildGroupObjectWidgetItems(QTreeWidget* pTreeWidget, QIconMap& mapIcons, const std::vector<gcmp::IElement*>& importedObjects);
    static void DeleteGroupObjectWidgetItem(QTreeWidget* pTreeWidget, gcmp::IElement* pDeletingObject);

    // 从Family中，去除导入对象的Family，并将其返回
    static std::vector<gcmp::IElement*> FilterOutImportedObjects(std::vector<gcmp::IFamily*>& pFamilies);

    static void RemoveSelectedFamlies(QList<QTreeWidgetItem *> &selectedItem, const std::wstring &cmdId);
    static void LoadFamily(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId);
    static void EditFamily(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId);
    static void RenameFamily(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId);
    static void CreateFamilyInstance(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId);
    static void EditFamilyTypeParameter(QTreeWidgetItem * pTreeItem);

    static void TrigerGroupAction(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId, const std::wstring& actionType);
    static void TrigerGroupListAction(QList<QTreeWidgetItem *> &selectedItem, const std::wstring &cmdId, const std::wstring& actionType);
    // 删除非族导入对象
    static void RemoveImportedObject(QTreeWidgetItem * pTreeItem, const std::wstring &cmdId);

    static QString GetIconPathForFamilyRootItem();
    static QString GetIconPathByFamilyCategoryName(const std::wstring& categoryName);
    static QString GetIconPathByFamilyName(const std::wstring& familyName);
    static QString GetIconPathByFamilyTypeName(const std::wstring& familyTypeName);
    static QString GetIconPathForImportedObject();
    static QString GetIconPathForCADSheetCategory();
    static QString GetIconPathForCADSheet();
    static QString GetIconPathForSKPCategory();
    static QString GetIconPathForSKP();
private:
    QFamilyTreeWidgetUtil();
    ~QFamilyTreeWidgetUtil();
};